package com.xdap.table.service.impl;

import com.xdap.api.constant.ComponentType;
import com.xdap.api.moudle.formconfig.pojo.FormComponent;
import com.xdap.api.moudle.formconfig.pojo.XdapFormConfig;
import com.xdap.api.moudle.privateapaas.datamodel.pojo.ModelWithFieldVo;
import com.xdap.common.dao.InitFormDao;
import com.xdap.common.utils.ExcelUtil;
import com.xdap.common.utils.InitDateFormatUtil;
import com.xdap.motor.utils.StringUtils;
import com.xdap.table.service.InitTableRelService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class InitTableRelServiceImpl implements InitTableRelService {

    @Autowired
    private InitFormDao initFormDao;

    @Override
    public String init(String filePath, String formId) {
        if (!filePath.endsWith(".xlsx")) {
            filePath = filePath + "\\低代码业务表关系-" + InitDateFormatUtil.getCurrentYyyyMmDdHhMiSs() + ".xlsx";
        }
        // 创建文件对象
        File file = new File(filePath);

        OutputStream fos = null;
        XSSFWorkbook workbook = null;
        try {
            // 如果不存在，或者不是一个文件，直接新建一个响应的对象
            if (!file.exists() || !file.isFile()) {
                file.createNewFile();
            }

            fos = new FileOutputStream(file);
            workbook = new XSSFWorkbook();
            List<String> sheetNames = new ArrayList<>();
            if (StringUtils.isBlank(formId)) {
                List<XdapFormConfig> allEnableXdapFormConfig = initFormDao.getAllEnableXdapFormConfig();

                // 处理每个表内的参数情况
                for (XdapFormConfig xdapFormConfig : allEnableXdapFormConfig) {
                    String sheetName = xdapFormConfig.getFormName();
                    long count = sheetNames.stream().filter(s -> s.equals(sheetName)).count();
                    sheetNames.add(sheetName);
                    if (count > 0) {
                        initSheet(workbook, xdapFormConfig, sheetName + count);
                    } else {
                        initSheet(workbook, xdapFormConfig, sheetName);

                    }
                }
            } else {
                XdapFormConfig xdapFormConfig = initFormDao.getXdapFormConfig(formId);
                initSheet(workbook, xdapFormConfig, xdapFormConfig.getFormName());
            }


            workbook.write(fos);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (workbook != null) {
                    workbook.close();
                    log.info("ExcelUtil.java ->> exportExcel() ->> 关闭Workbook资源");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            log.info("========================= ExcelUtil.java ->> exportExcel()导出数据到Excel中 ->> 结束 =========================");
        }


        return null;
    }


    public List<FormComponent> getSonFc(List<FormComponent> formComponents) {
        List<FormComponent> allChild = new ArrayList<>();
        if (CollectionUtils.isEmpty(formComponents)) {
            return null;
        }
        // 获取所有有子表的信息的数据
        List<FormComponent> hasChildList = formComponents.stream()
                .filter(fc -> CollectionUtils.isNotEmpty(fc.getChildren()))
                .collect(Collectors.toList());

        if (CollectionUtils.isNotEmpty(hasChildList)) {
            for (FormComponent fcData : hasChildList) {
                List<FormComponent> children = fcData.getChildren();
                List<FormComponent> sonFc = getSonFc(children);
                allChild.addAll(sonFc);
            }
        }

        List<FormComponent> sonTables = formComponents.stream()
                .filter(fc -> ComponentType.FORM_WIDGET_SON_TABLE.equals(fc.getComponentType()))
                .collect(Collectors.toList());
        allChild.addAll(sonTables);
        return sonTables;
    }


    /**
     * @auth lishushu
     * @2023/5/9 14:47
     * @desc {生成一个具体的sheet页}
     **/
    private void initSheet(XSSFWorkbook workbook, XdapFormConfig xdapFormConfig, String sheetName) {


        List<String> rowName = new ArrayList<>();
        rowName.add("表名称");
        rowName.add("表中文名称");
        rowName.add("关联表");

        List<ModelWithFieldVo> modelWithFieldVoList = xdapFormConfig.getModelWithFieldVoList();
        List<List> dataList = new ArrayList<>();

        // 获取关联表
        List<FormComponent> formComponents = xdapFormConfig.getDetailPage().getFormComponents();

        for (ModelWithFieldVo mw : modelWithFieldVoList) {
            List data = new ArrayList();
            // 命名主子表
            String modelCode = mw.getModelCode();
            String modelName = mw.getModelName();
            data.add(modelCode);
            Boolean mainModel = mw.getMainModel();
            // 查询主表内的fc
            String relTables = getRelTables(formComponents, modelCode);

            if (mainModel) {
                // 主表
                data.add(modelName + "(主)");
            } else {
                // 子表
                data.add(modelName);
                // 副表
                List<FormComponent> sonFc = getSonFc(formComponents);
                relTables += getRelTables(sonFc, modelCode);

            }

            data.add(relTables);
            dataList.add(data);
        }

        ExcelUtil.exportExcel(workbook, rowName, dataList, sheetName);

    }


    private String getRelTables(List<FormComponent> formComponents, String modelCode) {
        String tables = "";
        // 数据选择格式
        List<FormComponent> selTables = formComponents.stream()
                .filter(fc -> ComponentType.FORM_DATA_SELECTOR.equals(fc.getComponentType())
                        && modelCode.equals(fc.getModelCode()))
                .collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(selTables)) {
            List<String> selTable = new ArrayList<>();
            for (FormComponent fcData : selTables) {
                selTable.add(fcData.getModelCode() + "(" + fcData.getModelName() + ")");
            }
            tables += selTable.stream().distinct().collect(Collectors.joining(","));
        }
        // 数据字典格式
        List<FormComponent> dicTables = formComponents.stream()
                .filter(fc -> ComponentType.FORM_SELECT_INPUT.equals(fc.getComponentType())
                        && modelCode.equals(fc.getModelCode()))
                .collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(dicTables)) {
            tables += ",apaas_data_dictionary_value(字典表)";
        }

        // 部门格式
        List<FormComponent> deptTables = formComponents.stream()
                .filter(fc -> ComponentType.FORM_DEPARTMENT_SELECT.equals(fc.getComponentType()))
                .collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(deptTables)) {
            tables += ",xdap_departments(部门表)";
        }

        // 人员格式
        List<FormComponent> usersTables = formComponents.stream()
                .filter(fc -> ComponentType.FORM_PEOPLE_SELECT.equals(fc.getComponentType())
                        && modelCode.equals(fc.getModelCode()))
                .collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(usersTables)) {
            tables += ",xdap_users(人员表)";
        }
        // 地址格式
        List<FormComponent> areaTables = formComponents.stream()
                .filter(fc -> ComponentType.FORM_WIDGET_AREA.equals(fc.getComponentType())
                        && modelCode.equals(fc.getModelCode()))
                .collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(areaTables)) {
            tables += ",xdap_province(地址表-xdap_manage_database数据库)";
        }
        // 布局格式内的字段
        List<FormComponent> layoutTables = formComponents.stream()
                .filter(fc -> ComponentType.FORM_TAB_LAYOUT.equals(fc.getComponentType())
                        || ComponentType.FORM_TAB_ITEM_LAYOUT.equals(fc.getComponentType()))
                .collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(layoutTables)) {
            for (FormComponent fcData : layoutTables) {
                List<FormComponent> children = fcData.getChildren();
                // 如果是分页布局
                String relTables = getRelTables(children, modelCode);
                tables += relTables;
            }
        }
        // --- 关联表单不计算在内
//        List<FormComponent> assoTables = formComponents.stream()
//                .filter(fc -> ComponentType.FORM_ASSOCIATION.equals(fc.getComponentType()))
//                .collect(Collectors.toList());


        return tables;
    }


}
